<?php
/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce(functions were originally part
 * of osCommerce, extracted, renamed and modified for use in gwtCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
/*
  Functions in this file originally from:

  osCommerce, Open Source E-Commerce Solutions
  http://www.oscommerce.com

  Copyright (c) 2007 osCommerce
  Copyright (c) 2009 Eat Local Food, LLC

  Released under the GNU General Public License
*/

function sanitize_string($string)
{

//TBD: Look into this:
//return preg_replace("/[^ {}a-zA-Z0-9_.-]/i", "", urldecode($get_var));

	$string = preg_replace('# +#', ' ', trim($string));

	return preg_replace("/[<>]/", '_', $string);
}

function trusted_prepare_input($value) {
	if ($value == null) {
		return null;
	}
	else if (is_string($value)) {
		return trim(stripslashes($value));
	} 
	elseif (is_array($value)) {
		reset($value);
		while (list($key, $value1) = each($value)) {
			$value[$key] = trusted_prepare_input($value1);
		}
		return $value;
	} 
	else {
		return $value;
	}
}

function prepare_input($value)
{
	if ($value == null) {
		return null;
	}
	elseif (is_string($value)) {
		return trim(sanitize_string(stripslashes($value)));
	} 
	elseif (is_array($value)) {
		reset($value);
		while (list($key, $value1) = each($value)) {
			$value[$key] = prepare_input($value1);
		}
		return $value;
	} 
	else {
		return $value;
	}
}

function returnBoolean($value)
{
	$returnBool = false;
	if ($value == "true")
		$returnBool = true;
	return $returnBool;
}

function db_perform($table, $data, $action = 'insert', $parameters = '')
{
	reset($data);
	if ($action == 'insert') 
	{
		$sql = 'insert into ' . $table . ' (';
		while (list($columns, ) = each($data)) {
			$sql .= $columns . ', ';
		}
      		$sql = substr($sql, 0, -2) . ') values (';
		reset($data);
		while (list(, $value) = each($data)) {
			switch ((string)$value) {
				case 'now()':
					$sql .= 'now(), ';
					break;
				case 'null':
					$sql .= 'null, ';
					break;
				default:
					$sql .= '\'' . mysql_real_escape_string($value) . '\', ';
            				break;
				}
		}
		$sql = substr($sql, 0, -2) . ')';
	} 
	elseif ($action == 'update')
	{
		$sql = 'update ' . $table . ' set ';
		while (list($columns, $value) = each($data)) {
			switch ((string)$value) {
				case 'now()':
					$sql .= $columns . ' = now(), ';
					break;
				case 'null':
					$sql .= $columns .= ' = null, ';
					break;
				default:
					$sql .= $columns . ' = \'' . mysql_real_escape_string($value) . '\', ';
					break;
			}
		}
		$sql = substr($sql, 0, -2) . ' where ' . $parameters;
	}
    	return mysql_query($sql) or die(mysql_error());
}

function getAddresses($accountId, $default_addressId)
{
	$sqlQuery = 'select a.address_book_id, a.entry_gender, a.entry_company, a.entry_firstname, a.entry_lastname, a.entry_street_address, ' .
	'a.entry_suburb, a.entry_postcode, a.entry_city, a.entry_state, ' .
	'z.zone_id, z.zone_code, z.zone_name, ' .
	'c.countries_id, c.countries_name, c.countries_iso_code_2, c.countries_iso_code_3, c.address_format_id ' .
	'from ' . TABLE_ADDRESS_BOOK . ' a, ' . TABLE_ZONES . ' z, ' . TABLE_COUNTRIES . ' c ' .
	'where a.customers_id = \'' . (int)$accountId . '\' ' .
	'and a.entry_zone_id=z.zone_id and a.entry_country_id=z.zone_country_id ' .
	'and a.entry_country_id=c.countries_id ';
	$dataReturned = mysql_query($sqlQuery) or die(mysql_error());
	$i = 0;
	while($row = mysql_fetch_array($dataReturned))
	{
		$addressId = (int)$row['address_book_id'];
			
		$default_address = false;
		if ($addressId == $default_addressId)
		{
			$default_address = true;
		}
		$value{$i}{'default'}= (boolean)$default_address;

		$value{$i}{'id'}= $addressId;
		$value{$i}{'gender'}= $row['entry_gender'];
		$value{$i}{'company'}= $row['entry_company'];
		$value{$i}{'firstname'}= $row['entry_firstname'];
		$value{$i}{'lastname'}= $row['entry_lastname'];
		$value{$i}{'street_address'}= $row['entry_street_address'];
		$value{$i}{'suburb'}= $row['entry_suburb'];
		$value{$i}{'postcode'}= $row['entry_postcode'];
		$value{$i}{'city'}= $row['entry_city'];
		$value{$i}{'zone_id'}= $row['zone_id'];
		$value{$i}{'state'}= $row['zone_code'];
		$value{$i}{'country'}= $row['countries_name'];
		$value{$i}{'country_id'}= $row['countries_id'];
		$value{$i}{'country_iso_code_2'}= $row['countries_iso_code_2'];
		$value{$i}{'country_iso_code_3'}= $row['countries_iso_code_3'];
		$value{$i}{'address_format_id'}=$row['address_format_id'];
		$i++;
	}
	return $value;
}


function get_tax_rate($class_id, $country_id, $zone_id)
{
	$sqlQuery = "select sum(tax_rate) as tax_rate from " . TABLE_TAX_RATES . " tr left join " . TABLE_ZONES_TO_GEO_ZONES . " za on (tr.tax_zone_id = za.geo_zone_id) left join " . TABLE_GEO_ZONES . " tz on (tz.geo_zone_id = tr.tax_zone_id) where (za.zone_country_id is null or za.zone_country_id = '0' or za.zone_country_id = '" . (int)$country_id . "') and (za.zone_id is null or za.zone_id = '0' or za.zone_id = '" . (int)$zone_id . "') and tr.tax_class_id = '" . (int)$class_id . "' group by tr.tax_priority";
	$dataReturned = mysql_query($sqlQuery) or die(mysql_error());
	$i = 0;
	$tax_multiplier = 1.0;
	while($row = mysql_fetch_array($dataReturned))
	{
		$tax_multiplier *= 1.0 + ($row['tax_rate'] / 100);
		$i++;
	}
	$tax_rate = ($tax_multiplier - 1.0) * 100;
	
	return $tax_rate;
}

function get_tax_description($class_id, $country_id, $zone_id)
{
	$tax_description = '';
	$sqlQuery = "select tax_description from " . TABLE_TAX_RATES . " tr left join " . TABLE_ZONES_TO_GEO_ZONES . " za on (tr.tax_zone_id = za.geo_zone_id) left join " . TABLE_GEO_ZONES . " tz on (tz.geo_zone_id = tr.tax_zone_id) where (za.zone_country_id is null or za.zone_country_id = '0' or za.zone_country_id = '" . (int)$country_id . "') and (za.zone_id is null or za.zone_id = '0' or za.zone_id = '" . (int)$zone_id . "') and tr.tax_class_id = '" . (int)$class_id . "' order by tr.tax_priority";
	$dataReturned = mysql_query($sqlQuery) or die(mysql_error());
	$i = 0;
	while($row = mysql_fetch_array($dataReturned))
	{
		$tax_description .= $row['tax_description'] . ' + ';
		$i++;
	}
	if ($i > 0) $tax_description = substr($tax_description, 0, -3);//remove final +.

	return $tax_description;
}

////
//! Send email (text/html) using MIME
// This is the central mail function. The SMTP Server should be configured
// correct in php.ini
// Parameters:
// $to_name           The name of the recipient, e.g. "Jan Wildeboer"
// $to_email_address  The eMail address of the recipient,
//                    e.g. jan.wildeboer@gmx.de
// $email_subject     The subject of the eMail
// $email_text        The text of the eMail, may contain HTML entities
// $from_email_name   The name of the sender, e.g. Shop Administration
// $from_email_adress The eMail address of the sender,
//                    e.g. info@mytepshop.com

function send_email($to_name, $to_email_address, $email_subject, $email_text, $from_email_name, $from_email_address, $trap_exceptions=true)
{
	$return_boolean = false;
	try {
	if (SEND_EMAILS != 'true') return false;
	
	if (!validate_email_format($to_email_address, true))
	{
		$email_text = 'INVALID TO EMAIL ADDRESS: ' . $to_email_address . ' FOR ' . $to_name . ' SENDING TO FROM EMAIL ADDRESS \n\n' . $email_text;
		$to_email_address = $from_email_address;
	}

	require_once("includes/classes/mime.php");
	require_once("includes/classes/email.php");
	// Instantiate a new mail object
	$message = new email(array('X-Mailer: osCommerce Mailer'));

	// Build the text version
	$text = strip_tags($email_text);
	if (EMAIL_USE_HTML == 'true') {
		$message->add_html($email_text, $text);
	} else {
		$message->add_text($text);
	}

	// Send message
	$message->build_message();
	$return_boolean = $message->send($to_name, $to_email_address, $from_email_name, $from_email_address, $email_subject);
	}
	catch(Exception $e) {
		if ($trap_exceptions) {
		}
		else {
			throw $e;
		}
	}
}

function validate_email_format($email_address, $force_address_check=false)
{	
	if (returnBoolean(ENTRY_EMAIL_ADDRESS_FORMAT_CHECK) || $force_address_check)
	{
		if(!preg_match('/^[_A-z0-9-]+((\.|\+)[_A-z0-9-]+)*@[A-z0-9-]+(\.[A-z0-9-]+)*(\.[A-z]{2,4})$/', $email_address))
		{
			return false;
		}
		else if (returnBoolean(ENTRY_EMAIL_ADDRESS_CHECK) || $force_address_check)
		{
    			list($name, $domain) = preg_split('/@/',$email_address);
			if (!checkdnsrr($domain,'MX'))
			{
				return false;
			}
		}
	}
	return true;
}

function get_account_name($account_id)
{
	$sqlQuery = "select customers_firstname, customers_lastname from " . TABLE_CUSTOMERS . " where customers_id =" . $account_id;
	$dataReturned = mysql_query($sqlQuery) or die(mysql_error());
	while($row = mysql_fetch_array($dataReturned))
	{
		$name = $row['customers_firstname'] . " " . $row['customers_lastname'];
	}
	return $name;
}

function get_account_email($account_id)
{
	$sqlQuery = "select customers_email_address from " . TABLE_CUSTOMERS . " where customers_id =" . $account_id;
	$dataReturned = mysql_query($sqlQuery) or die(mysql_error());
	while($row = mysql_fetch_array($dataReturned))
	{
		$email = $row['customers_email_address'];
	}
	return $email;
}

function formatBytes($bytes, $precision = 2) {
    $units = array('B', 'kB', 'MB', 'GB', 'TB');
  
    $bytes = max($bytes, 0);
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
    $pow = min($pow, count($units) - 1);
  
    $bytes /= pow(1024, $pow);
  
    return round($bytes, $precision) . $units[$pow];
}


function get_rightsize_image($imagename, $width_max, $height_max)
{
	if ($imagename == null || strlen($imagename) == 0) {
		return array("",0,0);
	}
	$index = strrpos($imagename, ".");
	$base = substr($imagename, 0, $index);
	$cache_imagename = 'cache_' . $width_max . '_' . $height_max . '_' . $base . '.jpg';
	$cache_imagefile = DIR_FS_CATALOG_IMAGES . 'products/' . $cache_imagename;
	if (file_exists($cache_imagefile))
	{
		list($width, $height, $type) = getimagesize($cache_imagefile);
		return array($cache_imagename, $width, $height);
	}
	else {
		$imagefile = DIR_FS_CATALOG_IMAGES . 'products/' . $imagename;
		if (! file_exists($imagefile))
		{
			return array($imagename,0,0);
		}
		else {
			list($width, $height, $type) = getimagesize($imagefile);
			//Create resized image
			if ($width > $width_max || $height > $height_max) {
				$ratio = $width/$height;
				if ($width_max/$height_max > $ratio) {$width_max = floor($height_max*$ratio);} else {$height_max = floor($width_max/$ratio);}
				switch ($type) {
				case 1:   //   gif -> jpg
					$img_src = imagecreatefromgif($imagefile);
					break;
				case 2:   //   jpeg -> jpg
					$img_src = imagecreatefromjpeg($imagefile); 
					break;
				case 3:  //   png -> jpg
					$img_src = imagecreatefrompng($imagefile);
					break;
				}
				$img_dst = imagecreatetruecolor($width_max, $height_max);  //  resample
				$bool = imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $width_max, $height_max, $width, $height);
				imagejpeg($img_dst, $cache_imagefile,100);    //  save new image
				imagedestroy($img_src);        
				imagedestroy($img_dst);	
				
				list($width, $height, $type) = getimagesize($cache_imagefile);
				return array($cache_imagename, $width, $height);
			}
			//Use original image
			else {
				return array($imagename, $width, $height);
			}
		}
	}

	return array("",0,0);
}

function isAdministrator($accountId)
{
	if ($accountId < 1) return false;

	$sqlQuery = 'select r.roles_name ' .
	'from ' . TABLE_ROLES . ' r, ' . TABLE_ROLES_TO_CUSTOMERS . ' rc ' .
	'where r.roles_id=rc.roles_id and rc.customers_id=' . $accountId . ' ' .
	'order by r.roles_name';
	$dataReturned = mysql_query($sqlQuery) or die(mysql_error());
	while($row = mysql_fetch_array($dataReturned))
	{
		$role = $row['roles_name'];
		if ($role == 'administrator') return true;
	}
	return false;
}


////
// Parse search string into indivual objects
function parse_search_string($search_str = '', &$objects) {
	$search_str = trim(strtolower($search_str));
	// Break up $search_str on whitespace; quoted string will be reconstructed later
	//DEPRECATED:$pieces = split('[[:space:]]+', $search_str);
	$pieces = preg_split("/[\s,]+/", $search_str);
	$objects = array();
	$tmpstring = '';
	$flag = '';
	for ($k=0; $k<count($pieces); $k++) {
		while (substr($pieces[$k], 0, 1) == '(') {
			$objects[] = '(';
			if (strlen($pieces[$k]) > 1) {
				$pieces[$k] = substr($pieces[$k], 1);
			} else {
				$pieces[$k] = '';
			}
		}
		$post_objects = array();
		while (substr($pieces[$k], -1) == ')')	{
			$post_objects[] = ')';
			if (strlen($pieces[$k]) > 1) {
				$pieces[$k] = substr($pieces[$k], 0, -1);
			} else {
				$pieces[$k] = '';
			}
		}

		// Check individual words
		if ( (substr($pieces[$k], -1) != '"') && (substr($pieces[$k], 0, 1) != '"') ) {
			$objects[] = trim($pieces[$k]);

			for ($j=0; $j<count($post_objects); $j++) {
				$objects[] = $post_objects[$j];
			}
		} else {
			/* This means that the $piece is either the beginning or the end of a string.
 			* So, we'll slurp up the $pieces and stick them together until we get to the
 			* end of the string or run out of pieces.
			*/

			// Add this word to the $tmpstring, starting the $tmpstring
			$tmpstring = trim(preg_replace('/"/', ' ', $pieces[$k]));
			// Check for one possible exception to the rule. That there is a single quoted word.
			if (substr($pieces[$k], -1 ) == '"') {
				// Turn the flag off for future iterations
				$flag = 'off';

				$objects[] = trim($pieces[$k]);
	
				for ($j=0; $j<count($post_objects); $j++) {
					$objects[] = $post_objects[$j];
				}

				unset($tmpstring);

				// Stop looking for the end of the string and move onto the next word.
				continue;
			}

			// Otherwise, turn on the flag to indicate no quotes have been found attached to this word in the string.
			$flag = 'on';

			// Move on to the next word
			$k++;

			// Keep reading until the end of the string as long as the $flag is on
			while ( ($flag == 'on') && ($k < count($pieces)) ) {
				while (substr($pieces[$k], -1) == ')') {
					$post_objects[] = ')';
					if (strlen($pieces[$k]) > 1) {
						$pieces[$k] = substr($pieces[$k], 0, -1);
					} else {
						$pieces[$k] = '';
					}
				}

				// If the word doesn't end in double quotes, append it to the $tmpstring.
				if (substr($pieces[$k], -1) != '"') {
					// Tack this word onto the current string entity
					$tmpstring .= ' ' . $pieces[$k];

					// Move on to the next word
					$k++;
					continue;
				} else {
					/* If the $piece ends in double quotes, strip the double quotes, tack the
 					* $piece onto the tail of the string, push the $tmpstring onto the $haves,
 					* kill the $tmpstring, turn the $flag "off", and return.
					*/
					$tmpstring .= ' ' . trim(preg_replace('/"/', ' ', $pieces[$k]));

					// Push the $tmpstring onto the array of stuff to search for
					$objects[] = trim($tmpstring);

					for ($j=0; $j<count($post_objects); $j++) {
						$objects[] = $post_objects[$j];
					}

					unset($tmpstring);

					// Turn off the flag to exit the loop
					$flag = 'off';
				}
			}
		}
	}

	// add default logical operators if needed
	$temp = array();
	for($i=0; $i<(count($objects)-1); $i++) {
		$temp[] = $objects[$i];
		if ( ($objects[$i] != 'and') &&
			 ($objects[$i] != 'or') &&
			 ($objects[$i] != '(') &&
			 ($objects[$i+1] != 'and') &&
			 ($objects[$i+1] != 'or') &&
			 ($objects[$i+1] != ')') ) {
			$temp[] = ADVANCED_SEARCH_DEFAULT_OPERATOR;
		}
	}
	$temp[] = $objects[$i];
	$objects = $temp;

	$keyword_count = 0;
	$operator_count = 0;
	$balance = 0;
	for($i=0; $i<count($objects); $i++) {
		if ($objects[$i] == '(') $balance --;
		if ($objects[$i] == ')') $balance ++;
		if ( ($objects[$i] == 'and') || ($objects[$i] == 'or') ) {
			$operator_count ++;
		} elseif ( ($objects[$i]) && ($objects[$i] != '(') && ($objects[$i] != ')') ) {
			$keyword_count ++;
		}
	}

	if ( ($operator_count < $keyword_count) && ($balance == 0) ) {
		return true;
	} else {
		return false;
	}
}
?>
